//
//  LSYReadPageViewController.m
//  LSYReader
//
//  Created by Labanotation on 16/5/30.
//  Copyright © 2016年 okwei. All rights reserved.
//
#import "LSYReadPageViewController.h"
#import "LSYCatalogViewController.h"
#import "LSYReadViewController.h"
#import "LSYChapterModel.h"
#import "LSYMenuView.h"
#import "EVAlertView.h"
#import "UIView+Toast.h"
#import "LSYAlertSourceView.h"
#import "UIImage+ImageEffects.h"
#import "LSYNoteModel.h"
#import "LSYMarkModel.h"
#import <objc/runtime.h>
#import "NSString+HTML.h"
#import "WKProgressHUD.h"
#import "LSYBook.h"
#import "LSYNetUtil.h"
#import "LSYRuleService.h"
#import "LSYNovelService.h"
#import "LSYFileUtil.h"
#import "LSYBookManager.h"
#define AnimationDelay 0.3

@interface LSYReadPageViewController ()<UIPageViewControllerDelegate,UIPageViewControllerDataSource,LSYMenuViewDelegate,UIGestureRecognizerDelegate,LSYCatalogViewControllerDelegate,LSYReadViewControllerDelegate,LSYAlertSourceViewDelegate>
{
    NSUInteger _chapter;    //当前显示的章节
    NSUInteger _page;       //当前显示的页数
    NSUInteger _chapterChange;  //将要变化的章节
    NSUInteger _pageChange;     //将要变化的页数
    BOOL _isTransition;     //是否开始翻页
}
@property (nonatomic,strong) UIPageViewController *pageViewController;
@property (nonatomic,getter=isShowBar) BOOL showBar; //是否显示状态栏
@property (nonatomic,strong) LSYMenuView *menuView; //菜单栏
@property (nonatomic,strong) LSYCatalogViewController *catalogVC;   //侧边栏
@property (nonatomic,strong) UIView * catalogView;  //侧边栏背景
@property (nonatomic,strong) LSYReadViewController *readView;   //当前阅读视图
@end

@implementation LSYReadPageViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[LSYReadConfig shareInstance].theme];
    [self addChildViewController:self.pageViewController];
    [self downlodHtml:_model.record.chapter page:_model.record.page block:^(BOOL isNet) {
        [_pageViewController setViewControllers:@[[self readViewWithChapter:_model.record.chapter page:_model.record.page]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    }];
    _chapter = _model.record.chapter;
    _page = _model.record.page;
    [self.view addSubview:self.menuView];
    
    [self addChildViewController:self.catalogVC];
    [self.view addSubview:self.catalogView];
    [self.catalogView addSubview:self.catalogVC.view];
    //添加笔记
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addNotes:) name:LSYNoteNotification object:nil];
}

-(void)addNotes:(NSNotification *)no
{
    LSYNoteModel *model = no.object;
    model.recordModel = [_model.record copy];
    [[_model mutableArrayValueForKey:@"notes"] addObject:model];    //这样写才能KVO数组变化
    [EVAlertView showAlertViewWithMessage:@"保存笔记成功"];
}

-(BOOL)prefersStatusBarHidden
{
    return !_showBar;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
-(void)showToolMenuView
{
    [_readView.readView cancelSelected];
    NSString * key = [NSString stringWithFormat:@"%d_%d",(int)_model.record.chapter,(int)_model.record.page];
    
    id state = _model.marksRecord[key];
    state?(_menuView.topView.state=1): (_menuView.topView.state=0);
    [self.menuView showAnimation:YES];
    if (_model.chapters.count<=_chapter) {
        [_menuView.topView setTitle:@"Error"];
    } else {
        [_menuView.topView setTitle:_model.chapters[_chapter].title];
    }
}
#pragma mark - utils
- (BOOL)downlodHtml:(NSInteger)chapterNum page:(NSInteger)page block:(void(^)(BOOL isNet))block{
    if (_model.type == ReaderNet) {
        LSYBook *book = _model.netBook;
        if (book.chapters.count<=chapterNum) {
            block(YES);
            return YES;
        }
        LSYChapter *chapter =book.chapters[chapterNum];
        if (![LSYNetUtil cachedChapter:chapter]){
            [WKProgressHUD showInView:self.view withText:@"加载中..." animated:YES];
            [LSYNovelService getChapterContent:chapter book:book block:^(NSString *content) {
                [WKProgressHUD dismissAll:YES];
                if (block) {
                    block(YES);
                }
            }];
            [self downloadNearChapter:chapterNum book:book];
            return YES;
        } else {
            if (block) {
                block(NO);
            }
            //get next chapter
            [self downloadNearChapter:chapterNum book:book];
        }
    } else {
        if (block) {
            block(NO);
        }
    }
    return NO;
}

- (void)downloadNearChapter:(NSInteger)chapterNum book:(LSYBook *)book {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSInteger next = MIN(chapterNum+1, book.chapters.count-1);
        [LSYNovelService getChapterContent:book.chapters[next] book:book block:nil];
        NSInteger last = MAX(0, chapterNum -1);
        [LSYNovelService getChapterContent:book.chapters[last] book:book block:nil];
    });
}

#pragma mark - init
-(LSYMenuView *)menuView
{
    if (!_menuView) {
        _menuView = [[LSYMenuView alloc] init];
        _menuView.hidden = YES;
        _menuView.delegate = self;
        _menuView.recordModel = _model.record;
    }
    return _menuView;
}
-(UIPageViewController *)pageViewController
{
    if (!_pageViewController) {
        _pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
        _pageViewController.delegate = self;
        _pageViewController.dataSource = self;
        // fix pan and tap event occures the same time
        UITapGestureRecognizer *tap;
        UIPanGestureRecognizer *pan;
        for (UIGestureRecognizer *gr in _pageViewController.view.gestureRecognizers) {
            gr.delegate = self;
            if ([gr isKindOfClass:[UITapGestureRecognizer class]]) {
                tap = (UITapGestureRecognizer *)gr;
            }
            if ([gr isKindOfClass:[UIPanGestureRecognizer class]]) {
                pan = (UIPanGestureRecognizer *)gr;
            }
        }
        [tap requireGestureRecognizerToFail:pan];
        [self.view addSubview:_pageViewController.view];
    }
    return _pageViewController;
}
-(LSYCatalogViewController *)catalogVC
{
    if (!_catalogVC) {
        _catalogVC = [[LSYCatalogViewController alloc] init];
        _catalogVC.readModel = _model;
        _catalogVC.catalogDelegate = self;
    }
    return _catalogVC;
}
-(UIView *)catalogView
{
    if (!_catalogView) {
        _catalogView = [[UIView alloc] init];
        _catalogView.backgroundColor = [UIColor clearColor];
        _catalogView.hidden = YES;
        [_catalogView addGestureRecognizer:({
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hiddenCatalog)];
            tap.delegate = self;
            tap;
        })];
    }
    return _catalogView;
}
#pragma mark - CatalogViewController Delegate
-(void)catalog:(LSYCatalogViewController *)catalog didSelectChapter:(NSUInteger)chapter page:(NSUInteger)page
{
    [self hiddenCatalog];
    __weak typeof (self) weakSelf = self;
    [self downlodHtml:chapter page:page block:^(BOOL isNet) {
        [_pageViewController setViewControllers:@[[self readViewWithChapter:chapter page:page]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf.menuView hiddenAnimation:NO];
        }];
        [self updateReadModelWithChapter:chapter page:page];
    }];
}
#pragma mark -  UIGestureRecognizer Delegate
//解决TabView与Tap手势冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
        return NO;
    }
    return  YES;
}
#pragma mark - Privite Method
-(void)catalogShowState:(BOOL)show
{
    show?({
        _catalogView.hidden = !show;
        _catalogView.frame = CGRectMake(-ViewSize(self.view).width, 0, 2*ViewSize(self.view).width, ViewSize(self.view).height);
        [UIView animateWithDuration:AnimationDelay animations:^{
            _catalogView.frame = CGRectMake(0, 0,ViewSize(self.view).width, ViewSize(self.view).height);
            
        } completion:^(BOOL finished) {
            [_catalogView insertSubview:[[UIImageView alloc] initWithImage:[self blurredSnapshot]] atIndex:0];
        }];
    }):({
        if ([_catalogView.subviews.firstObject isKindOfClass:[UIImageView class]]) {
            [_catalogView.subviews.firstObject removeFromSuperview];
        }
        [UIView animateWithDuration:AnimationDelay animations:^{
             _catalogView.frame = CGRectMake(-ViewSize(self.view).width, 0, ViewSize(self.view).width, ViewSize(self.view).height);
        } completion:^(BOOL finished) {
            _catalogView.hidden = !show;
            
        }];
    });
}
-(void)hiddenCatalog
{
    [self catalogShowState:NO];
}
- (UIImage *)blurredSnapshot
{
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)), NO, 1.0f);
    [self.view drawViewHierarchyInRect:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) afterScreenUpdates:NO];
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIImage *blurredSnapshotImage = [snapshotImage applyLightEffect];
    UIGraphicsEndImageContext();
    return blurredSnapshotImage;
}
#pragma mark - Menu View Delegate
-(void)menuViewDidHidden:(LSYMenuView *)menu
{
     _showBar = NO;
    [self setNeedsStatusBarAppearanceUpdate];
}
-(void)menuViewDidAppear:(LSYMenuView *)menu
{
    _showBar = YES;
    [self setNeedsStatusBarAppearanceUpdate];
    
}
-(void)menuViewInvokeCatalog:(LSYBottomMenuView *)bottomMenu
{
    [_menuView hiddenAnimation:NO];
    [self catalogShowState:YES];
    
}

-(void)menuViewJumpChapter:(NSUInteger)chapter page:(NSUInteger)page
{
    __weak typeof (self) weakSelf = self;
    [self downlodHtml:chapter page:page block:^(BOOL isNet) {
        [_pageViewController setViewControllers:@[[self readViewWithChapter:chapter page:page]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [strongSelf.menuView hiddenAnimation:NO];
        }];
        [self updateReadModelWithChapter:chapter page:page];
    }];
}
-(void)menuViewFontSize:(LSYBottomMenuView *)bottomMenu
{

    [_model.record.chapterModel updateFont];
    [_pageViewController setViewControllers:@[[self readViewWithChapter:_model.record.chapter page:(_model.record.page>_model.record.chapterModel.pageCount-1)?_model.record.chapterModel.pageCount-1:_model.record.page]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    [self updateReadModelWithChapter:_model.record.chapter page:(_model.record.page>_model.record.chapterModel.pageCount-1)?_model.record.chapterModel.pageCount-1:_model.record.page];
}

-(void)menuViewMark:(LSYTopMenuView *)topMenu
{
    NSString * key = [NSString stringWithFormat:@"%d_%d",(int)_model.record.chapter,(int)_model.record.page];
    id state = _model.marksRecord[key];
    if (state) {
//如果存在移除书签信息
        [_model.marksRecord removeObjectForKey:key];
        [[_model mutableArrayValueForKey:@"marks"] removeObject:state];
    }
    else{
//记录书签信息
        LSYMarkModel *model = [[LSYMarkModel alloc] init];
        model.date = [NSDate date];
        model.recordModel = [_model.record copy];
        [[_model mutableArrayValueForKey:@"marks"] addObject:model];
        [_model.marksRecord setObject:model forKey:key];
    }
    _menuView.topView.state = !state;
}

- (void)menuViewBack:(LSYTopMenuView *)topMenu {
    if ([[LSYBookManager manager] existBook:self.model]) {
        [[LSYReadUtilites getCurrentVC] dismissViewControllerAnimated:YES completion:nil];
    } else {
        [EVAlertView showMessageAlertView:@"加入书架？" commitButton:@"加入" cancelButton:@"取消" dismissBlock:^(EVAlertViewStruct result) {
            if (result.buttonIndex == EVAlertViewButtonIndexCommit) {
                [[LSYBookManager manager] addBook:self.model];
            }
            [[LSYReadUtilites getCurrentVC] dismissViewControllerAnimated:YES completion:nil];
        }];
    }
}

- (void)menuViewSource:(LSYTopMenuView *)topMenu {
    __weak typeof(self) weakSelf = self;
    __block LSYAlertSourceView *linkAlertView =  [[[UINib nibWithNibName:@"LSYAlertSourceView" bundle:nil]instantiateWithOwner:self options:nil]lastObject];
    linkAlertView.autoresizingMask = UIViewAutoresizingNone;
    linkAlertView.layer.cornerRadius = 5;
    linkAlertView.mDelegate = self;
    linkAlertView.rule = _model.netBook.rule;
    __weak typeof(linkAlertView) weakAlertView = linkAlertView;
    linkAlertView.refreshBlock = ^(){
        [LSYNovelService batchSearch:_model.netBook block:^(NSMutableArray *rules) {
            __strong typeof (weakAlertView) strongAlertView = weakAlertView;
            weakSelf.model.netBook.rules = rules;
            [strongAlertView setRules:rules];
            [strongAlertView endRefresh];
            [[LSYBookManager manager] saveToFile];
        }];
    };
    if (_model.netBook.rules.count > 0) {
        __block EVAlertView *alertLinkAlertView = [[EVAlertView alloc]initWithContentView:linkAlertView CompletionBlock:^{
            linkAlertView.rules = weakSelf.model.netBook.rules;
        } dismissBlock:^(EVAlertViewStruct result) {
            [alertLinkAlertView dismissIntemidialy];
            alertLinkAlertView = nil;
        }];
        [alertLinkAlertView show];
    } else {
        [self.view makeToast:@"正在搜索更多源" duration:2 position:CSToastPositionCenter];
        [LSYNovelService batchSearch:_model.netBook block:^(NSMutableArray *rules) {
            weakSelf.model.netBook.rules = rules;
            __block EVAlertView *alertLinkAlertView = [[EVAlertView alloc]initWithContentView:linkAlertView CompletionBlock:^{
                linkAlertView.rules = rules;
            } dismissBlock:^(EVAlertViewStruct result) {
                alertLinkAlertView = nil;
            }];
            [alertLinkAlertView show];
            [[LSYBookManager manager] saveToFile];
        }];
    }
}

#pragma mark - LSYAlertSourceViewDelegate method
- (void)selectedRule:(LSYParseModel *)rule {
    //重新获取
    [WKProgressHUD showInView:self.view withText:@"切换中..." animated:YES];
    [LSYNovelService searchBookAndChapter:_model rule:rule block:^(BOOL success) {
        [WKProgressHUD dismissAll:NO];
        if (success) {
            __weak typeof(self) weakSelf = self;
            [self downlodHtml:_model.record.chapter page:_model.record.page block:^(BOOL isNet) {
                [_pageViewController setViewControllers:@[[self readViewWithChapter:_model.record.chapter page:_model.record.page]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL finished) {
                    [WKProgressHUD dismissAll:YES];
                    [weakSelf.view makeToast:[NSString stringWithFormat:@"%@切换成功",rule.name] duration:2 position:CSToastPositionCenter];
                    [[LSYBookManager manager] saveToFile];
                }];
            }];
        } else {
            [self.view makeToast:[NSString stringWithFormat:@"%@切换失败",rule.name] duration:2 position:CSToastPositionCenter];
        }
    }];
}
#pragma mark - Create Read View Controller
// add network check 
-(LSYReadViewController *)readViewWithChapter:(NSUInteger)chapter page:(NSUInteger)page{
    if (_model.chapters.count<= chapter) {
        _readView = [[LSYReadViewController alloc] init];
        _readView.recordModel = _model.record;
        _readView.delegate = self;
        return _readView;
    }
    if (_model.record.chapter != chapter) {
        [_model.record.chapterModel updateFont];
        if (_model.type == ReaderEpub ||_model.type == ReaderNet) {
            if (_model.chapters[chapter].epubframeRef.count<=0) {
                NSString *chapterPath = [LSYFileUtil absolutePath:_model.chapters[chapter].chapterpath];
                NSString* html = [NSString stringWithContentsOfFile:chapterPath encoding:NSUTF8StringEncoding error:nil];
                _model.chapters[chapter].html = html;
                _model.chapters[chapter].content = [html stringByConvertingHTMLToPlainText];
                [_model.chapters[chapter] parserEpubToDictionary];
            }
            [ _model.chapters[chapter] paginateEpubWithBounds:CGRectMake(0,0, [UIScreen mainScreen].bounds.size.width-LeftSpacing-RightSpacing, [UIScreen mainScreen].bounds.size.height-TopSpacing-BottomSpacing)];
        }
    }
    _readView = [[LSYReadViewController alloc] init];
    _readView.recordModel = _model.record;
    if (_model.type == ReaderEpub ||_model.type == ReaderNet) {
        _readView.type = _model.type;
        if (_model.chapters[chapter].epubframeRef.count<=0) {
            NSLog(@"%@",_model.chapters[chapter].chapterpath);
            NSString *chapterPath = [LSYFileUtil absolutePath:_model.chapters[chapter].chapterpath];
            NSString* html = [NSString stringWithContentsOfFile:chapterPath encoding:NSUTF8StringEncoding error:nil];
            _model.chapters[chapter].html = html;
            _model.chapters[chapter].content = [html stringByConvertingHTMLToPlainText];
            [_model.chapters[chapter] parserEpubToDictionary];
            [_model.chapters[chapter] paginateEpubWithBounds:CGRectMake(0,0, [UIScreen mainScreen].bounds.size.width-LeftSpacing-RightSpacing, [UIScreen mainScreen].bounds.size.height-TopSpacing-BottomSpacing)];
        }
        _page = MIN(page, _model.chapters[chapter].pageCount-1);
        _readView.epubFrameRef = _model.chapters[chapter].epubframeRef[_page];
        _readView.imageArray = _model.chapters[chapter].imageArray;
        _readView.content = _model.chapters[chapter].content;
    }
    else{
        _readView.type = ReaderTxt;
        _readView.content = [_model.chapters[chapter] stringOfPage:page];
    }
    _readView.delegate = self;
    NSLog(@"_readGreate %@",[NSDate date]);
    return _readView;
}
-(void)updateReadModelWithChapter:(NSUInteger)chapter page:(NSUInteger)page
{
    _chapter = chapter;
    _page = MIN(page, _model.chapters[chapter].pageCount -1);
    _model.record.chapterModel = _model.chapters[chapter];
    _model.record.chapter = _chapter;
    _model.record.page = _page;
    [LSYReadModel updateLocalModel:_model url:_model.resourceUrl];
}
#pragma mark - Read View Controller Delegate
-(void)readViewEndEdit:(LSYReadViewController *)readView
{
    for (UIGestureRecognizer *ges in self.pageViewController.view.gestureRecognizers) {
        if ([ges isKindOfClass:[UIPanGestureRecognizer class]]) {
            ges.enabled = YES;
            break;
        }
    }
}
-(void)readViewEditeding:(LSYReadViewController *)readView
{
    for (UIGestureRecognizer *ges in self.pageViewController.view.gestureRecognizers) {
        if ([ges isKindOfClass:[UIPanGestureRecognizer class]]) {
            ges.enabled = NO;
            break;
        }
    }
}
#pragma mark -PageViewController DataSource
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    _pageChange = _page;
    _chapterChange = _chapter;
    if (_chapterChange==0 &&_pageChange == 0) {
        return [self readViewWithChapter:_chapterChange page:_pageChange];
    }
    if (_pageChange==0) {
        _chapterChange--;
        _pageChange = _model.chapters[_chapterChange].pageCount-1;
    }
    else{
        _pageChange--;
    }
    __weak typeof (self) weakSelf = self;
    BOOL isNet = [self downlodHtml:_chapterChange page:_pageChange block:^(BOOL isNet) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (isNet) {
            [strongSelf.pageViewController setViewControllers:@[[self readViewWithChapter:_chapterChange page:_pageChange]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:^(BOOL finished) {
                __strong typeof (weakSelf) strongSlf = weakSelf;
                [strongSlf.menuView hiddenAnimation:NO];
            }];
        }
    }];
    if (isNet) {
        return nil;
    }
    return [self readViewWithChapter:_chapterChange page:_pageChange];
}
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    _pageChange = _page;
    _chapterChange = _chapter;
    if (_pageChange == _model.chapters.lastObject.pageCount-1 && _chapterChange == _model.chapters.count-1) {
        return [self readViewWithChapter:_chapterChange page:_pageChange];
    }
    if (_pageChange == _model.chapters[_chapterChange].pageCount-1) {
        _chapterChange++;
        _pageChange = 0;
    }
    else{
        _pageChange++;
    }
    __weak typeof (self) weakSelf = self;
    BOOL isNet = [self downlodHtml:_chapterChange page:_pageChange block:^(BOOL isNet) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (isNet) {
            [strongSelf.pageViewController setViewControllers:@[[weakSelf readViewWithChapter:_chapterChange page:_pageChange]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished) {
                __strong typeof (weakSelf) strongSlf = weakSelf;
                [strongSlf.menuView hiddenAnimation:NO];
            }];
        }
    }];
    if (isNet) {
        return nil;
    }
    return [self readViewWithChapter:_chapterChange page:_pageChange];
}
#pragma mark -PageViewController Delegate
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    if (!completed) {
        LSYReadViewController *readView = previousViewControllers.firstObject;
        _readView = readView;
        _page = readView.recordModel.page;
        _chapter = readView.recordModel.chapter;
    }
    else{
        [self updateReadModelWithChapter:_chapter page:_page];
    }
}
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers
{
    _chapter = _chapterChange;
    _page = _pageChange;
}

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    _pageViewController.view.frame = self.view.frame;
    _menuView.frame = self.view.frame;
    self.catalogVC.view.frame = CGRectMake(0, 0, ViewSize(self.view).width-100, ViewSize(self.view).height);
    [self.catalogVC reload];
    
}

- (void)dealloc {
    NSLog(@"---");
}
@end
